package org.brisling.medical.queryService;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;

import org.brisling.authorize.shiro.ShiroSecurityService;
import org.brisling.base.domain.ListDomain;
import org.brisling.base.service.AbstractBaseQueryService;
import org.brisling.common.ConstSysParam;
import org.brisling.common.exception.DangerousOperatorException;
import org.brisling.common.util.DateUtil;
import org.brisling.medical.domain.LargeCost;
import org.brisling.medical.domain.MedicalRecipel;
import org.brisling.medical.service.RecipelService;
import org.brisling.medical.vo.VOLargeCostPatient;
import org.brisling.medical.vo.VOQueryLargeCost;
import org.brisling.sysman.queryService.QueryDictionaryService;
import org.brisling.sysman.queryService.QueryPermissionService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.servlet.ModelAndView;

/**
 * 
 * <p>
 * Title: QueryLargecostService
 * </p>
 * <p>
 * Description: 大额住院费用监控查询service
 * </p>
 * <p>
 * Company: 长沙东勤信息科技发展有限公司
 * </p>
 * 
 * @author shura
 * @since 1.0
 * @version 1.0
 * @date 2016年7月20日 下午10:06:38
 */
@RestController
@RequestMapping("/largeCost/query")
public class QueryLargeCostService extends AbstractBaseQueryService<LargeCost> {

	@Autowired
	private QueryDictionaryService dicService;
	@Autowired
	private RecipelService qrService;

	@Autowired
	private ShiroSecurityService shiroSecurityService;

	@Autowired
	private QueryDictionaryService qryDictionaryService;

	@Autowired
	private QueryPermissionService qryPermissionService;

	public QueryLargeCostService() {
		this.moduleName = ConstSysParam.MODULE_LARGE_COST;
		this.subSystem = ConstSysParam.SUBSYSTEM_MEDICAL;
		this.tableName = this.getTableName(LargeCost.class);
		this.clazz = LargeCost.class;
		typeMap = this.getTypeMap(clazz);

		orderMap.put("sortedid", null);
	}

	@PersistenceContext(unitName = ConstSysParam.SUBSYSTEM_SYSMAN)
	@Autowired
	protected void setEntityManager(EntityManager entityManager) {
		this.entityManager = entityManager;
	}

	@RequestMapping("/mainPage.action")
	public ModelAndView getMainPage() {
		return this.getBizMainPage();
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.brisling.service.sysman.DepartmentServiceInf#getEditPage()
	 */
	@RequestMapping("/editPage.action")
	public ModelAndView getEditPage() {
		return this.getBizEditPage();
	}

	/*
	 * @RequestMapping("/getListDomain.action") public ListDomain<LargeCost>
	 * getListDomain(@RequestParam(value="page",required=false) Integer page,
	 * 
	 * @RequestParam(value="rows",required=false) Integer rows,
	 * 
	 * @RequestParam(value="condition",required=false) String condition,
	 * 
	 * @RequestParam(value="sort",required=false) String sort){
	 * 
	 * StringBuilder sb = new StringBuilder(); String sql = "";
	 * if(condition!=null){ String whereCorse=String.format(sb.append(
	 * "deptid = %1$s").toString(),condition); sql = String.format(this.TW_SQL,
	 * this.tableName,whereCorse); }else{ sql = String.format(this.T_SQL,
	 * this.tableName); }
	 * 
	 * return super.getPagedListDomain(page,rows,sql); }
	 */

	@RequestMapping("/getListDomain.action")
	public ListDomain<LargeCost> getListDomain(@RequestBody(required = false) String body) {

		Map<String, Object> map = this.getBodyParam(body);
		// Map<String,String> paramMap = (Map<String, String>)
		// map.get(ConstSysParam.CONDITION_MAP_KEY);
		String userid = shiroSecurityService.getCurrentUserIdentify();
		if (!this.isSuperDept(userid, ConstSysParam.QUERY_ALL, "query_medical_all")) {
			if (isManageJob(userid)) {
				addJobDeptConditionToMap(userid, map, "dept_code");
			} else {
				addUsridConditionToMap(userid, map, "doct_code");
			}
			// 查找科室数据
		}
		// 查询表
		return super.getListDomainByConditionAndOrder(null, map, typeMap, orderMap, true);
	}

	@RequestMapping("/getList.action")
	public List<LargeCost> getList(@RequestParam(value = "page", required = false) Integer page,
			@RequestParam(value = "rows", required = false) Integer rows,
			@RequestParam(value = "deptid", required = false) Integer deptid,
			@RequestParam(value = "sort", required = false) String sort) {

		StringBuilder sb = new StringBuilder();
		String sql = "";
		if (deptid != null) {
			String whereCorse = String.format(sb.append("\"deptid\" = %1$d").toString(), deptid);
			sql = String.format(this.TW_SQL, this.tableName, whereCorse);
		} else {
			sql = String.format(this.T_SQL, this.tableName);
		}

		return super.getPagedList(page, rows, sql);
	}

	@SuppressWarnings("unchecked")
	@RequestMapping("/getAllListDomain.action")
	public ListDomain<LargeCost> getAllListDomain(@RequestBody(required = false) String body) {

		Map<String, Object> map = this.getBodyParam(body);
		Map<String, String> paramMap = (Map<String, String>) map.get(ConstSysParam.CONDITION_MAP_KEY);
		String userid = shiroSecurityService.getCurrentUserIdentify();
		if (!this.isSuperDept(userid, ConstSysParam.QUERY_ALL, "query_medical_all")) {
			if (isManageJob(userid)) {
				addJobDeptConditionToMap(userid, map, "dept_code");
			} else {
				addUsridConditionToMap(userid, map, "doct_code");
			}
			// 查找科室数据
		} else {
			paramMap.put("dept_code_in", "-1");
		}
		// 查询表
		return super.getListDomainByConditionAndOrder(null, map, typeMap, orderMap, true);
	}

	@SuppressWarnings("unchecked")
	@RequestMapping("/getPatientListDomain.action")
	public ListDomain<Object> getPatienetListDomain(@RequestBody(required = false) String body)
			throws DangerousOperatorException {

		Map<String, Object> map = this.getBodyParam(body);
		Map<String, String> paramMap = (Map<String, String>) map.get(ConstSysParam.CONDITION_MAP_KEY);
		Map<String, Object> condition = (Map<String, Object>) map.get("condition");
		if (condition == null || condition.isEmpty()) {
			return null;
		}
		String mym = (String) condition.get("monitor_year_month");
		String[] yearMonth = mym.split("-");
		Integer year = null, month = null;
		if (yearMonth.length > 0 && yearMonth[0] != null && Integer.valueOf(yearMonth[0]) > 0) {
			year = Integer.valueOf(yearMonth[0]);
		}
		if (yearMonth.length > 1 && yearMonth[1] != null && Integer.valueOf(yearMonth[1]) > 0
				&& Integer.valueOf(yearMonth[1]) < 12) {
			month = Integer.valueOf(yearMonth[1]);
		}
		String[] monthDay = null;
		if (year == null || month == null) {
			monthDay = DateUtil.getYestodayMonthDay();
		} else {
			monthDay = DateUtil.getMonthDay(year, month);
		}
		String doct_code = (String) condition.get("doct_code");
		if (doct_code == null || doct_code.length() < 1) {
			return null;
		}
		String userid = shiroSecurityService.getCurrentUserIdentify();
		if (!this.isSuperDept(userid, ConstSysParam.QUERY_ALL, "query_medical_all")) {
			if (isManageJob(userid)) {
				addJobDeptConditionToMap(userid, map, "dept_code");
			} else {
				addUsridConditionToMap(userid, map, "doct_code");
			}
			// 查找科室数据
		} else {
			paramMap.put("dept_code_in", "-1");
		}
		String sql = null;
		sql = qryDictionaryService.getSqlByBizcode("large-cost-patient-query");
		if (sql == null || sql.equals("") || sql.length() < 1) {
			return null;
		}
		sql = String.format(sql, year + "-" + month, monthDay[0], monthDay[1], doct_code);
		// getPagedMapListDomain(sql, map, VOQueryLargeCost.class, true);
		// 查询表
		return getPagedMapVo(sql, map);
	}

	@SuppressWarnings("rawtypes")
	private ListDomain<Object> getPagedMapVo(String sql, Map<String, Object> conditionMap)
			throws DangerousOperatorException {
		// super.getAllList(sql);
		ListDomain<LinkedHashMap> domains = super.getPagedMapListDomain(sql, conditionMap, VOLargeCostPatient.class,
				true);
		ListDomain<Object> odomain = new ListDomain<Object>();
		if (domains != null) {
			List<Object> lists = reflectObjectMaps(VOLargeCostPatient.class, domains.getRows());
			odomain.setTotal(domains.getTotal());
			odomain.setRows(lists);
		} else {
			odomain.setTotal(0l);
			odomain.setRows(new ArrayList<Object>());
		}
		return odomain;

	}

	/**
	 * 根据用户id查找用户信息
	 * 
	 * @param id
	 *            用户id
	 * @return 用户信息记录
	 */
	@RequestMapping("/getOne.action")
	public LargeCost getOne(@RequestParam(value = "id", required = false) Long id) {
		return super.getOne(id);
	}

	/**
	 * 根据用户唯一编码查找用户信息
	 * 
	 * @param identify
	 *            用户唯一编码
	 * @return 用户信息记录
	 */
	@RequestMapping("/getOneByIdentify.action")
	public LargeCost getOneByIdentify(@RequestParam(value = "identify", required = false) String identify) {
		return super.getOneByIdentify(identify);
	}

	/**
	 * 大额住院费用弹窗
	 */

	@RequestMapping("/popPage.action")
	public ModelAndView getPopPage() {
		String userid = shiroSecurityService.getCurrentUserIdentify();
		String _page = "popMain";
		if (!this.isSuperDept(userid, ConstSysParam.QUERY_ALL, "query_large_cost")) {
			if (!isManageJob(userid)) {
				_page = "popDetail";
			}
		}
		return new ModelAndView("/medical/medical_large_cost/" + _page);
	}

	/**
	 * 根据传入的数据字典和ID，查询符合条件的sql语句的OneDomain
	 * 
	 * @param page
	 * @param rows
	 * @return
	 */
	@RequestMapping("/getSqlOneDomain.action")
	public ListDomain<LargeCost> getSqlOneDomain(@RequestBody(required = false) String body,
			@RequestParam(value = "sqlid", required = false) String sqlid) {

		Map<String, Object> conditionMap = getBodyParam(body);
		return super.getListDomainByConditionAndOrder(null, conditionMap, typeMap, orderMap, false);
	}

	/**
	 * 自动发送质询记录
	 * 
	 * @param userId
	 */
	public List<MedicalRecipel> autosave(String userId) {

		java.text.SimpleDateFormat format = new java.text.SimpleDateFormat("yyyy-MM-dd");
		String date_end = format.format((new Date()));

		return this.autosave(userId, date_end);
	}

	/**
	 * 自动发送质询记录
	 * 
	 * @param userId
	 */
	public List<MedicalRecipel> autosave(String userId, String date) {
		List<VOQueryLargeCost> lists = this.getLargecost("total_fee_wrong", date);

		Date _date = null;
		try {
			_date = (new SimpleDateFormat("yyyy-MM-dd")).parse(date);
		} catch (ParseException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		}
		ArrayList<MedicalRecipel> list = new ArrayList<MedicalRecipel>();
		if (lists != null) {
			for (VOQueryLargeCost e : lists) {
				MedicalRecipel tmp = this.largecostToMedicalRecipel(e, _date);

				if (tmp == null)
					continue;

				tmp.setCreateTime(_date);
				list.add(tmp);
			}
		}
		if (list.isEmpty()) {
			return null;
		}
		for (MedicalRecipel a : list) {
			if (a.getInquiry_reason() == null || a.getInquiry_reason().length() < 1) {
				System.out.println();
			}
			qrService.completeTask(userId, a);
		}
		return list;
	}

	/**
	 * 获取大额费用数据
	 * 
	 * @param bizcode
	 * @return
	 */
	public List<VOQueryLargeCost> getLargecost(String bizcode) {
		java.text.SimpleDateFormat format = new java.text.SimpleDateFormat("yyyy-MM-dd");
		String date_end = format.format((new Date()));
		return this.getLargecost(bizcode, date_end);
	}

	/**
	 * 获取大额费用数据
	 * 
	 * @param bizcode
	 * @param dateEnd
	 * @return
	 */
	public List<VOQueryLargeCost> getLargecost(String bizcode, String dateEnd) {
		String sql = dicService.getSqlByBizcode(bizcode);

		String date_start = DateUtil.getDateBefore(dateEnd, 15);
		sql = String.format(sql, date_start, dateEnd);
		try {
			return super.getClassedAllList(sql, VOQueryLargeCost.class);
		} catch (DangerousOperatorException e) {
			e.printStackTrace();
		}
		return null;
	}

	/**
	 * 获取大额费用数据
	 * 
	 * @param bizcode
	 * @return
	 */
	public List<VOQueryLargeCost> testLargecost(String bizcode, String _date) {
		String sql = dicService.getSqlByBizcode(bizcode);
		sql = String.format(sql, _date);
		try {
			return super.getClassedAllList(sql, VOQueryLargeCost.class);
		} catch (DangerousOperatorException e) {
			e.printStackTrace();
		}
		return null;
	}

	public void testInsert() {
		String _date = "2016-7-";

		for (int i = 1; i <= 31; i++) {
			String date = _date + i;
			testLargecost("total_fee_wrong", date);
		}
	}

	/**
	 * 获取大额费用数据
	 * 
	 * @param bizcode
	 * @return
	 */
	public List<LargeCost> getLargecostCount(String bizcode) {
		String sql = dicService.getSqlByBizcode(bizcode);
		java.text.SimpleDateFormat format = new java.text.SimpleDateFormat("yyyy-MM-dd");
		sql = String.format(sql, format.format((new Date().getTime() - (long) 24 * 60 * 60 * 1000 * 15)).toString());
		try {
			return super.getClassedAllList(sql, LargeCost.class);
		} catch (DangerousOperatorException e) {
			e.printStackTrace();
		}
		return null;
	}

	/**
	 * 
	 * @param list
	 * @param inquiryDate
	 * @return
	 * @legal problem 大额住院费用外科、内科标志写死为4、5，必须根据实际情况进行处理
	 */
	public MedicalRecipel largecostToMedicalRecipel(VOQueryLargeCost list, Date inquiryDate) {
		String Bizcode = qryPermissionService.getBizFlowConfig("recipel").getFullBizcode();
		String flowid = qryPermissionService.getBizFlowConfig("recipel").getFlowid();

		MedicalRecipel mr = new MedicalRecipel();
		mr.setInquiry_date(inquiryDate);
		mr.setInquiry_item("收费异常");
		mr.setInquiry_item_sub("大额住院费用");
		mr.setInquiry_item_subcode("185");
		mr.setInquiry_item_code("5");
		// 住院号
		mr.setZyhm(list.getZyhm());
		
		mr.setInhzospitalat(list.getINHZOSPITALAT());
		mr.setDoct_id(list.getDoct_code());
		mr.setDoct_name(list.getDoct_name());
		// 科室名称
		mr.setDoct_depart_name(list.getDoct_depart_name());
		// if (list.getDoct_depart_code()!=null) return null;
		mr.setDoct_depart_code(list.getDoct_depart_code());
		// mr.setZyhm("123");
		// 记录编号
		mr.setPatient_id(list.getPatient_id().toString());
		mr.setPatient_name(list.getPatient_name());
		mr.setPatient_type("2");
		// mr.setPatient_id("3333");
		java.text.SimpleDateFormat format = new java.text.SimpleDateFormat("yyyy-MM-dd");
		String today = new SimpleDateFormat("yyyy-MM-dd").format(inquiryDate);
		if (list.getParentid() == 4)
			mr.setInquiry_reason("从" + format.format(list.getINHZOSPITALAT()) + "起入院到" + today + "为止，内科的总额费用已达"
					+ list.getTatol_price() + "元");
		if (list.getParentid() == 5)
			mr.setInquiry_reason("从" + format.format(list.getINHZOSPITALAT()) + "起入院到" + today + "为止，外科的总额费用已达"
					+ list.getTatol_price() + "元");
		// test用
		mr.setFlowid(flowid);
		mr.setFullBizcode(Bizcode);
		return mr;
	}

	/**
	 * 执行自动统计
	 */
	public List<LargeCost> autoMonitor(Integer year, Integer month) {

		String[] yestodayMonth = null;
		if (year == null || month == null)
			yestodayMonth = DateUtil.getYestodayMonthDay();
		else {
			yestodayMonth = DateUtil.getMonthDay(year, month);
		}

		// 统计大额住院费用最新数据
		List<LargeCost> inlists = countLargeCost(yestodayMonth[2], yestodayMonth[0], yestodayMonth[1]);

		// 查询已有数据
		List<LargeCost> oldLists = this.getList(yestodayMonth[2]);
		LinkedHashMap<String, LargeCost> lmap = new LinkedHashMap<String, LargeCost>();

		// 将已有值存入临时map
		if (oldLists != null && oldLists.size() > 0) {

			for (int i = 0; i < oldLists.size(); i++) {
				LargeCost b = oldLists.get(i);
				String _key = null;
				if (b.getDoct_code() == null) {
					_key = b.getDept_code().toString();
				} else {
					_key = b.getDept_code() + "-" + b.getDoct_code();
				}
				lmap.put(_key, b);
			}
		}

		if (inlists != null) {

			if (lmap != null && lmap.size() > 0) {
				for (int i = 0; i < inlists.size(); i++) {
					LargeCost b = inlists.get(i);
					String _key = null;
					if (b.getDoct_code() == null) {
						_key = b.getDept_code().toString();
					} else {
						_key = b.getDept_code() + "-" + b.getDoct_code();
					}
					if (lmap.containsKey(_key)) {
						inlists.get(i).setId(lmap.get(_key).getId());
					}
					if (inlists.get(i).getMonitor_year_month() == null)
						inlists.get(i).setMonitor_year_month(yestodayMonth[2]);
				}
			} else {
				for (int i = 0; i < inlists.size(); i++) {
					if (inlists.get(i).getMonitor_year_month() == null)
						inlists.get(i).setMonitor_year_month(yestodayMonth[2]);
				}
			}

		}
		return inlists;
	}

	/**
	 * 统计大额住院费用情况
	 * 
	 * @param year_month
	 * @param startDate
	 * @param endDate
	 * @param countType
	 *            0,期间出院病人;1,期间在院病人
	 * @return
	 */
	@SuppressWarnings({ "static-access", "unused" })
	public List<LargeCost> countLargeCost(String year_month, String startDate, String endDate) {

		String today = new SimpleDateFormat("yyyy-MM-dd").format(new Date());
		Calendar cal = Calendar.getInstance();
		cal.add(Calendar.DATE, -1);
		String yesterday = new SimpleDateFormat("yyyy-MM-dd").format(cal.getTime());

		// 出院病人统计语句
		String[] sqlids = { "large_cost_all", "large_cost_dept", "large_cost_doct" };

		// 统计全院数据-住院

		List<String> sqls = new ArrayList<String>();
		for (int i = 0; i < sqlids.length; i++) {
			String sql = qryDictionaryService.getSqlByBizcode(sqlids[i]);
			if (sql != null) {
				sql = sql.format(sql, startDate, endDate);
				sqls.add(sql);
			}
		}
		// 所有数据
		List<LargeCost> lists = super.monitorCountBase(year_month, startDate, endDate, sqls);

		return lists;

	}

	/**
	 * 获取部门统计指标
	 * 
	 * @param body
	 * @return
	 */

	private List<LargeCost> getList(String monitor_year_month) {

		String sql = String.format("select * from %1$s where monitor_year_month='%2$s'", this.tableName,
				monitor_year_month);
		// 查询表
		return super.getAllList(sql);

	}

}